package com.scc.aop;
import com.alibaba.fastjson.JSONObject;
import com.scc.mapper.AdminOperationLogMapper;
import com.scc.pojo.AdminOperationLog;
import com.scc.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class AdminLogAspect {
    //注入接口
    @Autowired
    private AdminOperationLogMapper adminOperationLogMapper;

    //注入http请求对象
    @Autowired
    private HttpServletRequest request;

    //切点
    @Pointcut("execution(* com.scc.controller.AdminController.*(..))")
    public void AdminLogPointcut() {}

    @Around("AdminLogPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //排除登录时的操作日志记录
        String method = joinPoint.getSignature().getName();
        //如果相同直接返回
        //登录日志不记录
        if(method.equals("login")){
            return joinPoint.proceed();
        }
        //从请求的token(jwt令牌)中获取id,账号，权限
        String jwt = request.getHeader("token");

        //解析jwt
        Map<String, Object> claims = JwtUtil.parseJwt(jwt);

        //获取管理员的id
        Integer adminId = (Integer) claims.get("id");

        //获取管理员的账号
        String account = (String) claims.get("username");

        //获取管理员的权限
        Integer rights = (Integer) claims.get("rights");
        String adminRights = "无权管理员";
        ///判断是什么权限
        if(rights==1){
            adminRights = "有权管理员";
        }

        //操作时间
        LocalDateTime operationTimeNow = LocalDateTime.now();
        System.out.println(operationTimeNow);
        //格式化时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //类型转化为LocalDateTime
        LocalDateTime operationTime = LocalDateTime.parse(formatter.format(operationTimeNow), formatter);

        //获取操作方法的类名
        String className = joinPoint.getTarget().getClass().getName();

        //获取操作的方法名
        String methodName = joinPoint.getSignature().getName();

        //获取方法的形参
        Object[] args = joinPoint.getArgs();
        ///转化为字符串
        String methodParams = Arrays.toString(args);

        //获取方法的返回结果
        ///方法执行前获取当前时间
        Long startTime = System.currentTimeMillis();

        //执行方法
        Object result = joinPoint.proceed();
        //转化为json格式的字符串保存
        String resultValue = JSONObject.toJSONString(result);
        ///这几种情况不需要返回结果
        if(method.equals("getAdminOperationLogs")||method.equals("getEmpOnlineMsg")||method.equals("getEmpOperationLogsMsg")){
            //获取日志不记录结果
            resultValue = null;
        }else if(method.equals("deleteAdminOperationLogs")||method.equals("deleteEmpOnlineMsg")||method.equals("deleteEmpOperationLogsMsg")){
            //删除日志不记录结果
            resultValue = null;
        }

        ///方法执行后的时间
        Long endTime = System.currentTimeMillis();

        //获取方法的执行时间
        Long costTime = endTime - startTime;

        //获取管理员日志对象并且添加数据
        AdminOperationLog operationLog = new AdminOperationLog();
        //添加数据
        operationLog.setAdminId(adminId);
        operationLog.setAccount(account);
        operationLog.setRights(adminRights);
        operationLog.setOperateTime(operationTime);
        operationLog.setClassName(className);
        operationLog.setMethodName(methodName);
        operationLog.setMethodParams(methodParams);
        operationLog.setResultValue(resultValue);
        operationLog.setCostTime(costTime);
        //调用mapper接口添加进入数据库
        adminOperationLogMapper.insertAdminOperationLog(operationLog);

        //记录日志
        log.info("管理员操作日志记录:{}",operationLog);

        //返回一个方法的结果
        return result;
    }
}
